#ifndef IMAGE_C
#define IMAGE_C


#define TABLE_STATE

#include "Image.h"
#include "Imagemap.c"
#include "displayuser.h"


#define INDICATOR_STATUS_PER_BYTE   4           /* No of Indicators per Byte */
#define INDICATOR_REQUESTS_PER_BYTE 8           /* No of Indicators requests */

#define PROMPT_INDEX                0 + (promptId / INDICATOR_STATUS_PER_BYTE)

#define PROMPT_ON                   (uint8_t)(ON << (promptId % INDICATOR_STATUS_PER_BYTE))
#define PROMPT_BLINK                (uint8_t)(IMAGE_REQUEST_BLINK << (promptId % INDICATOR_STATUS_PER_BYTE))

#define FramePromptBlinkPattern(x)       (uint8_t)(0x11 << (x%INDICATOR_STATUS_PER_BYTE))


#define IMAGE_CONTENT_SIZE     20

static uint8_t imageBlinkState;
static uint8_t imageBlinkTimer;

uint8_t image[IMAGE_MAX_SIZE];

uint8_t imageDisplayed[IMAGE_MAX_SIZE];

static uint8_t imageFieldContents[IMAGE_CONTENT_SIZE];


static void ImageCopy(void);


uint8_t *ImageAddress(void)
{
	return imageDisplayed;
}

/*---------------------------------------------------------------------------*
 |  ImagePromptSet
 |
 |  Turn a prompt on, off or set blink request for the prompt.
 |  See Image.h for details
 *---------------------------------------------------------------------------*/
void ImagePromptSet(uint8_t promptId, uint8_t onOffBlink)
{
	if ( onOffBlink )
        imageFieldContents[0 + promptId / INDICATOR_STATUS_PER_BYTE] |= (onOffBlink << (promptId % INDICATOR_STATUS_PER_BYTE));
	else
	    imageFieldContents[0 + promptId / INDICATOR_STATUS_PER_BYTE] &= (uint8_t)(~(ON << (promptId % INDICATOR_STATUS_PER_BYTE)));  
}

/*---------------------------------------------------------------------------*
 |  ImageOperation
 |
 |  Service pending requests. See Image.h for details.
 *---------------------------------------------------------------------------*/
 //50ms
void ImageOperation(void)
{
	uint8_t promptId;  /* Index Prompt ID */
	uint8_t prompt;
	
	if(!imageBlinkTimer)
	{
	 /*----------------------------------------*
        |  Toggle the state and Reset the timer
        *----------------------------------------*/
	    if(imageBlinkState == ON)
		{
			imageBlinkState = OFF;
			imageBlinkTimer = IMAGE_BLINK_OFF;
		}
		else
		{
			imageBlinkState = ON;
			imageBlinkTimer = IMAGE_BLINK_ON;
		}
	}
	
	for(promptId = 0; promptId < IMAGE_PROMPT_COUNT; promptId++)
	{
		prompt = FramePromptBlinkPattern(promptId) & imageFieldContents[PROMPT_INDEX];
		if ( (prompt == PROMPT_ON) || (imageBlinkState == ON && prompt == PROMPT_BLINK) )
		{
			image[IMAGE_PROMPT_INDEX[promptId]] |= IMAGE_PROMPT_MASK[promptId];
		}
		else
		{
			image[IMAGE_PROMPT_INDEX[promptId]] &= (uint8_t)~IMAGE_PROMPT_MASK[promptId];
		}
	}
	ImageCopy();
}

/*---------------------------------------------------------------------------*
 |  ImageProcess
 |
 |  Handles blinking. Called periodically at 10Hz. See Image.h for details.
 *---------------------------------------------------------------------------*/

void ImageProcess(void)
{
   if(imageBlinkTimer)
      imageBlinkTimer--;                        /* Decrement the Blink timer */
}

uint8_t ImageGetBlinkState(void)
{
	return imageBlinkState;
}

/*---------------------------------------------------------------------------*
 |  ImageCopy
 |
 |  Copies the constructed image to the image being displayed and syncs with 
 |  field contents
 |
 |  Entry:  No requirements
 |          
 |  Exit:   Returns nothing
 *---------------------------------------------------------------------------*/
typedef uint16_t TRamRange;
typedef uint8_t * TRamAddress;  
 
 void RamCopy(TRamAddress dest, TRamAddress source, TRamRange n)
{
   while(n--)
      dest[n] = source[n];
}
 
 
static void ImageCopy(void)
{
    RamCopy(imageDisplayed, image, IMAGE_MAX_SIZE);
}

#endif